﻿using Cheems.Interface.MQTT;
using MQTTnet.Server;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cheems.Service.MQTT
{
    public class MqttServerService : IMqttServer
    {
        #region 内部对象
        MqttServerFactory mqttServerFactory;
        MqttServerOptions mqttServerOptions;
        MqttServer mqttServer;
        #endregion


        public event Action<Exception> OnException;
        public event Action OnOpened;
        public event Action OnClosed;
        public event Action<string, byte[]> OnReceiveMessage;

        /// <summary>
        /// 打开连接
        /// </summary>
        /// <param name="port"></param>
        /// <returns></returns>
        public async Task<bool> OpenAsync(int port)
        {
            try
            {
                mqttServerFactory = new MqttServerFactory();
                mqttServerOptions = new MqttServerOptionsBuilder()
                .WithDefaultEndpoint()
                .WithDefaultEndpointPort(port)
                .WithDefaultEndpointBoundIPAddress(System.Net.IPAddress.Any)
                .Build();
                mqttServer = mqttServerFactory.CreateMqttServer(mqttServerOptions);
                mqttServer.ApplicationMessageNotConsumedAsync += MqttServer_ApplicationMessageNotConsumedAsync;
                await mqttServer.StartAsync();
                if (mqttServer.IsStarted)
                {
                    OnOpened?.Invoke();
                    return true;
                }
            }
            catch (Exception ex)
            {
                OnException?.Invoke(ex);
                return false;
            }
            return false;
        }


        private async Task MqttServer_ApplicationMessageNotConsumedAsync(ApplicationMessageNotConsumedEventArgs arg)
        {
            OnReceiveMessage?.Invoke(arg.ApplicationMessage.Topic, ConvertReadOnlySequenceToArray(arg.ApplicationMessage.Payload));
            await Task.Delay(1000);
        }

        static byte[] ConvertReadOnlySequenceToArray(ReadOnlySequence<byte> sequence)
        {
            // 如果是单段数据，直接复制到数组
            if (sequence.IsSingleSegment)
            {
                return sequence.First.ToArray();
            }

            // 多段数据，分段读取并合并到数组
            byte[] result = new byte[sequence.Length];
            sequence.CopyTo(result);
            return result;
        }
        /// <summary>
        /// 关闭连接
        /// </summary>
        /// <returns></returns>
        public async Task<bool> CloseAsync()
        {

            if (mqttServer != null)
            {
                try
                {

                    await mqttServer.StopAsync();
                    OnClosed?.Invoke();
                    return true;
                }
                catch (Exception ex)
                {
                    OnException?.Invoke(ex);
                    return false;
                }
            }
            return true;
        }


    }
}
